<!DOCTYPE HTML>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script>
function testPixels(actualPixels, expectedPixels, pixelFormat)
{
    var tolerance = 0;
    if (pixelFormat == "float16")
        tolerance = 0.01;
    assert_array_approx_equals(actualPixels, expectedPixels, tolerance);
}


function generateFillStyle(red, green, blue, alpha) {
    return "rgba(" + red + "," + green + "," + blue + "," + alpha + ")";
}

function createSourceCanvasAndExpectedResult(testScenario)
{
    var canvas = document.createElement("canvas");
    canvas.width = 2;
    canvas.height = 2;
    var ctx = canvas.getContext('2d', {colorSpace: testScenario.colorSpace,
                                       pixelFormat: testScenario.pixelFormat});
    ctx.fillStyle = generateFillStyle(155, 27, 27, testScenario.alpha);
    ctx.fillRect(0, 0, 1, 1);
    ctx.fillStyle = generateFillStyle(27, 155, 27, testScenario.alpha);
    ctx.fillRect(1, 0, 1, 1);
    ctx.fillStyle = generateFillStyle(27, 27, 155, testScenario.alpha);
    ctx.fillRect(0, 1, 1, 1);
    ctx.fillStyle = generateFillStyle(27, 27, 27, testScenario.alpha);
    ctx.fillRect(1, 1, 1, 1);
    imageData = ctx.getImageData(0, 0, 2, 2, testScenario.colorSetting).data;
    var result = {};
    result.canvas = canvas;
    result.expectedPixels = imageData;
    return result;
}

function testScenarioToString(testScenario) {
    var str = "Source color space: " + testScenario.colorSpace +
              ", pixel format: " + testScenario.pixelFormat +
              ", alpha: " + testScenario.alpha;
    if (testScenario.hasOwnProperty('colorSpaceConversion'))
        str = str + ", intermediate color space: " +
                    testScenario.colorSpaceConversion;
    return str;
}

function runToBlobTest(testScenario) {
    var initVars = createSourceCanvasAndExpectedResult(testScenario);
    var srcCanvas = initVars.canvas;
    var expectedPixels = initVars.expectedPixels;
    var image = new Image();
    var t_dataurl = async_test("Test if toBlob is color managed: " +
        testScenarioToString(testScenario));
    image.onload = t_dataurl.step_func_done(function() {
        var dstCanvas = document.createElement("canvas");
        dstCanvas.width = 2;
        dstCanvas.height = 2;
        var ctx = dstCanvas.getContext('2d',
            {colorSpace: testScenario.colorSpace,
             pixelFormat: testScenario.pixelFormat});
        ctx.drawImage(image, 0, 0);
        var actualPixels = ctx.getImageData(0, 0, 2, 2, testScenario.colorSetting).data;
        testPixels(actualPixels, expectedPixels, testScenario.pixelFormat);
    });
    srcCanvas.toBlob(function(blob) {
        var urlCreator = window.URL || window.webkitURL;
        image.src = urlCreator.createObjectURL(blob);
    }, 'image/png', 1);
}

function runToDataURLTest(testScenario) {
    var initVars = createSourceCanvasAndExpectedResult(testScenario);
    var srcCanvas = initVars.canvas;
    var expectedPixels = initVars.expectedPixels;

    var image = new Image();
    var t_dataurl = async_test("Test if toDataURL is color managed: " +
        testScenarioToString(testScenario));
    image.onload = t_dataurl.step_func_done(function() {
        var dstCanvas = document.createElement("canvas");
        dstCanvas.width = 2;
        dstCanvas.height = 2;
        var ctx = dstCanvas.getContext('2d',
            {colorSpace: testScenario.colorSpace,
             pixelFormat: testScenario.pixelFormat});
        ctx.drawImage(image, 0, 0);
        var actualPixels = ctx.getImageData(0, 0, 2, 2, testScenario.colorSetting).data;
        testPixels(actualPixels, expectedPixels, testScenario.pixelFormat);
    });
    image.src = srcCanvas.toDataURL();
}

function runToBlobTestWithImageBitmap(testScenario) {
    var initVars = createSourceCanvasAndExpectedResult(testScenario);
    var srcCanvas = initVars.canvas;
    var expectedPixels = initVars.expectedPixels;

    var image = new Image();
    var t_dataurl = async_test("Test if toBlob is color managed with ImageBitmap: " +
        testScenarioToString(testScenario));
    image.onload = t_dataurl.step_func_done(function() {
        var options = {colorSpaceConversion: testScenario.colorSpaceConversion};
        var imagebitmap;
        var p1 = createImageBitmap(image, options).then(function(bitmap) {
            imagebitmap = bitmap });
        return Promise.all([p1]).then(
            t_dataurl.step_func_done(function() {
                var dstCanvas = document.createElement("canvas");
                dstCanvas.width = 2;
                dstCanvas.height = 2;
                var ctx = dstCanvas.getContext('2d',
                        {colorSpace: testScenario.colorSpace,
                        pixelFormat: testScenario.pixelFormat});
                ctx.drawImage(image, 0, 0);
                var actualPixels = ctx.getImageData(0, 0, 2, 2, testScenario.colorSetting).data;
                testPixels(actualPixels, expectedPixels, testScenario.pixelFormat);
        }), t_dataurl.step_func_done(function() {
            assert_true(false, "createImageBitmap promise rejected.");
        }));
    });
    srcCanvas.toBlob(function(blob) {
        var urlCreator = window.URL || window.webkitURL;
        image.src = urlCreator.createObjectURL(blob);
    }, 'image/png', 1);
}

function runToDataURLTestWithImageBitmap(testScenario) {
    var initVars = createSourceCanvasAndExpectedResult(testScenario);
    var srcCanvas = initVars.canvas;
    var expectedPixels = initVars.expectedPixels;

    var image = new Image();
    var t_dataurl = async_test("Test if toDataURL is color managed with ImageBitmap: " +
        testScenarioToString(testScenario));
    image.onload = t_dataurl.step_func_done(function() {
        var options = {colorSpaceConversion: testScenario.colorSpaceConversion};
        var imagebitmap;
        var p1 = createImageBitmap(image, options).then(function(bitmap) {
            imagebitmap = bitmap });
        return Promise.all([p1]).then(
            t_dataurl.step_func_done(function() {
                var dstCanvas = document.createElement("canvas");
                dstCanvas.width = 2;
                dstCanvas.height = 2;
                var ctx = dstCanvas.getContext('2d',
                        {colorSpace: testScenario.colorSpace,
                        pixelFormat: testScenario.pixelFormat});
                ctx.drawImage(image, 0, 0);
                var actualPixels = ctx.getImageData(0, 0, 2, 2, testScenario.colorSetting).data;
                testPixels(actualPixels, expectedPixels, testScenario.pixelFormat);
        }), t_dataurl.step_func_done(function() {
            assert_true(false, "createImageBitmap promise rejected.");
        }));
    });
    image.src = srcCanvas.toDataURL();
}

function runAllTests() {
    var colorSpaces = [
        {colorSpace: 'srgb', pixelFormat: 'uint8', imageFormat: 'uint8'},
        {colorSpace: 'srgb', pixelFormat: 'float16', imageFormat: 'float32'},
        {colorSpace: 'rec2020', pixelFormat: 'float16', imageFormat: 'float32'},
        {colorSpace: 'display-p3', pixelFormat: 'float16', imageFormat: 'float32'}];
    var alphaValues = [0.5, 1];
    var colorSettings = [
        {colorSpace: 'srgb', storageFormat: 'uint8'},
        {colorSpace: 'srgb', storageFormat: 'float32'},
        {colorSpace: 'rec2020', storageFormat: 'float32'},
        {colorSpace: 'display-p3', storageFormat: 'float32'}
        ];

    var testScenarioSet = [];
    for (var i = 0; i < colorSpaces.length; i++)
        for (var j = 0; j < alphaValues.length; j++) {
            var testScenario = {};
            testScenario.colorSpace = colorSpaces[i].colorSpace;
            testScenario.pixelFormat = colorSpaces[i].pixelFormat;
            testScenario.colorSetting = colorSettings[i];
            testScenario.alpha = alphaValues[j];
            testScenarioSet.push(testScenario);
        }

    for (var i = 0; i < 8; i++)
        runToBlobTest(testScenarioSet[i]);

    for (var i = 0; i < 8; i++)
        runToDataURLTest(testScenarioSet[i]);

    var colorSpaceConversions = ['default', 'srgb', 'linear-rgb', 'rec2020', 'display-p3'];
    var testScenarioSetWithImageBitmap = [];
    for (var i = 0; i < colorSpaces.length; i++)
        for (var j = 0; j < alphaValues.length; j++)
            for (var k = 0; k < colorSpaceConversions.length; k++) {
                var testScenario = {};
                testScenario.colorSpace = colorSpaces[i].colorSpace;
                testScenario.pixelFormat = colorSpaces[i].pixelFormat;
                testScenario.alpha = alphaValues[j];
                testScenario.colorSpaceConversion = colorSpaceConversions[k];
                testScenarioSetWithImageBitmap.push(testScenario);
            }

    for (var i = 0; i < 40; i++)
        runToBlobTestWithImageBitmap(testScenarioSetWithImageBitmap[i]);

    for (var i = 0; i < 40; i++)
        runToDataURLTestWithImageBitmap(testScenarioSetWithImageBitmap[i]);
}

runAllTests();

</script>